﻿using Microsoft.Extensions.DependencyInjection;
using Msung.Core.DI;
using Msung.Core.Helper;
using Msung.Core.Kafka;

namespace Msung.Core.Extensions
{
    public static class ServiceCollectionExtension
    {


        /// <summary>
        /// 根据配置 批量注入生产者
        /// </summary>
        /// <param name="services"></param>
        public static void AddKafkaProducers(this IServiceCollection services)
        {
            var baseoptions = AppSetting.KafkaBaseOptions;
            var producers = AppSetting.KafkaProducerOptions;
            foreach (var item in producers)
            {
                services.AddKafkaProducer(item.Topic, options =>
                {
                    options.Partition = item.Partition;
                    options.BootstrapServers = baseoptions.BootstrapServers;
                    options.InitializeCount = item.InitializeCount;
                    options.Key = item.Key;
                    options.Topic = item.Topic;
                });
            }
        }
        /// <summary>
        /// 根据配置 批量注入消费者
        /// </summary>
        /// <param name="services"></param>
        public static void AddKafkaConsumers(this IServiceCollection services)
        {
            var baseoptions = AppSetting.KafkaBaseOptions;
            var consumerOptions = AppSetting.KafkaConsumerOptions;
            if (baseoptions.BootstrapServers == null || baseoptions.BootstrapServers.Length <= 0)
            {
                throw new Exception("kafka服务器地址异常");
            }
            var assemblyList = RuntimeHelper.GetAllAssemblies();
            ///动态根据配置   创建消费者
            foreach (var item in assemblyList)
            {

                var typs = item.GetTypes().Where(oo => !oo.IsInterface
                && typeof(IKafkaConsumerListener).IsAssignableFrom(oo));
                foreach (var interfaceType in typs)
                {
                    var consumerOption = consumerOptions.Where(a => a.CallbackClass == interfaceType.Name).FirstOrDefault();
                    if (consumerOption == null) continue;
                    services.AddKafkaConsumer(a =>
                    {
                        a.BootstrapServers = baseoptions.BootstrapServers;
                        a.Subscribers = consumerOption.Subscribers;
                        a.GroupId = consumerOption.GroupId;
                    }).AddListener(interfaceType);
                }
            }
        }

        /// <summary>
        ///  批量注入业务服务 业务接口、实现类后缀 必须Service结尾
        /// </summary>
        /// <param name="services"></param>
        public static void AddService(this IServiceCollection services)
        {

            var assemblyList = RuntimeHelper.GetAllAssemblies();
            foreach (var item in assemblyList)
            {
                var types = item.GetTypes();
                var interfaceTypes = types.Where(oo => oo.IsInterface).Where(oo => oo.Name.EndsWith("Repository") || oo.Name.EndsWith("Service"));
                foreach (var interfaceType in interfaceTypes)
                {
                    //注入类型
                    var diType = interfaceType.GetInterfaces().FirstOrDefault(x => x.Name == nameof(ITransient) || x.Name == nameof(IScope) || x.Name == nameof(ISingleton));
                    var implType = types.FirstOrDefault(oo => oo.Name == interfaceType.Name.Substring(1) && !oo.IsInterface && !oo.IsAbstract);
                    if (diType == null || implType == null)
                        continue;
                    switch (diType.Name)
                    {
                        case nameof(ITransient):
                            services.AddTransient(interfaceType, implType);
                            break;
                        case nameof(IScope):
                            services.AddScoped(interfaceType, implType);
                            break;
                        case nameof(ISingleton):
                            services.AddSingleton(interfaceType, implType);
                            break;
                    }
                }
            }
        }
    }
}
